﻿using System;
using System.Net;
using System.Web.Http;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using TravelingWebApp.ViewModels;
using TravelingWebApp.Models;
using TravelingWebApp.Middleware;
using Microsoft.AspNetCore.Identity;
using System.Security.Claims;

namespace TravelingWebApp.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class AccountController : Controller
    {
        private SignInManager<User> _signInManager;
        private UserManager<User> _userManager;
        private RoleManager<IdentityRole> _roleManager;

        public AccountController(SignInManager<User> signInManager,
            UserManager<User> userManager, 
            RoleManager<IdentityRole> roleManager)
        {
            _signInManager = signInManager;
            _userManager = userManager;
            _roleManager = roleManager;
        }

        //钦定一个管理员
        [HttpGet]
        [Route("AddAdmin")]
        public async Task<string> AddAdmin()
        {
            User user = new User
            {
                Name = "Ceqiu",
                UserName = "Admin",
                PhoneNumber = "13752657410",
                Email = "charl_huang@qq.com"
            };
            var result = await _userManager.CreateAsync(user, "Hao123456*");
            if (result.Succeeded)
            {
                bool roleExists = await _roleManager.RoleExistsAsync("Administer");
                if (!roleExists)
                {
                    await _roleManager.CreateAsync(new IdentityRole("Administer"));
                }
                if (!await _userManager.IsInRoleAsync(user, "Administer"))
                {
                    await _userManager.AddToRoleAsync(user, "Administer");
                }
                if (!string.IsNullOrWhiteSpace(user.Email))
                {
                    Claim claim = new Claim(ClaimTypes.Email, user.Email);
                    await _userManager.AddClaimAsync(user, claim);
                }
                var resultSignIn = await _signInManager.PasswordSignInAsync(user.UserName, "Hao123456*", true, false);
                if (resultSignIn.Succeeded)
                {
                    return "true";
                }else
                {
                    return "cannot Login";
                 }
            }
            return "false";
        }

        [HttpGet]
        [Route("listUsers")]
        public ActionResult<string> listUsers()
        {
            var user =  _userManager.Users.ToList();
            return Ok(Json(user));
        }

        [Route("Login")]
        [HttpGet]
        public ActionResult<string> Login()
        {
            if (this.User.Identity.IsAuthenticated)
            {
                return Ok("Success");
            }
            return NotFound("Please use POST to login.");
        }

        [Route("Login")]
        [HttpPost]
        public async Task<ActionResult<string>> LoginPost([FromBody]LoginViewModel model)
        {
            if (ModelState.IsValid)
            {
                var result = await _signInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, false);
                if (result.Succeeded)
                {
                    return Ok("Success");
                }
                else
                {
                    ModelState.AddModelError("", "Faild to Login");
                    return BadRequest("Password Incorrect");
                }
            }
            else
            {
                NotFound("ModelError");
            }
            ModelState.AddModelError("", "Faild to Login");
            return NotFound("Unknonwn error");
        }

        [Route("Logout")]
        public async Task<ActionResult<string>> Logout()
        {
            await _signInManager.SignOutAsync();
            return Ok("Success");
        }

        [Route("Register")]
        [HttpPost]
        //[ValidateAntiForgeryToken]
        public async Task<ActionResult<string>> RegisterPost([FromBody]RegisterViewModel model)
        {
            if (ModelState.IsValid)
            {
                User user = new User
                {
                    Name = model.Name,
                    UserName = model.UserName,
                    PhoneNumber = model.PhoneNumber,
                    Email = model.Email
                };

                var result = await _userManager.CreateAsync(user, model.Password);
                if (result.Succeeded)
                {
                    bool roleExists = await _roleManager.RoleExistsAsync("USER");
                    if (!roleExists)
                    {
                        await _roleManager.CreateAsync(new IdentityRole("USER"));
                    }

                    if (!await _userManager.IsInRoleAsync(user, "USER"))
                    {
                        await _userManager.AddToRoleAsync(user, "USER");
                    }

                    if (!string.IsNullOrWhiteSpace(user.Email))
                    {
                        Claim claim = new Claim(ClaimTypes.Email, user.Email);
                        await _userManager.AddClaimAsync(user, claim);
                    }

                    var resultSignIn = await _signInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, false);
                    if (resultSignIn.Succeeded)
                    {
                        return Ok("Success");
                    }
                }
                foreach (var error in result.Errors)
                {
                    ModelState.AddModelError("", error.Description);
                }
                return BadRequest("用户名要求：不重复\n密码要求：至少7位、包含数字、包含符号");
            }
            return NotFound("ModelState invalid");
        }

        [Route("ChangePwd")]
        [HttpPost]
        //[ValidateAntiForgeryToken]
        public async Task<ActionResult<string>> ChangePwdPost([FromBody]ChangePwdViewModel changePwdModel)
        {
            if (ModelState.IsValid)
            {
                var userNow = await _userManager.GetUserAsync(User);
                var result = await _userManager.ChangePasswordAsync(userNow, changePwdModel.OldPassword, changePwdModel.NewPassword);
                if (result.Succeeded)
                {
                    return Ok("Success");
                }
            }
            return NotFound("ModelState invalid");
        }
        
        public ActionResult<bool> AccessDenied()
        {
            return false;
        }
    }
}